package dragon.social.core;

import dragon.social.core.QQ.QQConnectionFactory;
import dragon.social.core.rewrite.MysqlJdbcUserConnectionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.UserIdSource;
import org.springframework.social.config.annotation.ConnectionFactoryConfigurer;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionSignUp;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.social.security.AuthenticationNameUserIdSource;
import org.springframework.social.security.SpringSocialConfigurer;

import javax.sql.DataSource;

/**
 * spring social 全局配置
 */
@Configuration
public class SocialConfigAdapter extends SocialConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired(required = false)
    ConnectionSignUp connectionSignUp;

    @Override
    public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) {
        super.addConnectionFactories(connectionFactoryConfigurer, environment);
        //添加工厂
        connectionFactoryConfigurer.addConnectionFactory(new QQConnectionFactory(ConstantProperties.SPEnum.QQ));
    }

    /**
     * 配置JdbcUserConnectionRepository
     */
    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        /*
        三个构造方法：
        1、数据源，连数据库
        2、ConnectionFactoryLocator，用来确定本实例是对应哪个ConnectionFactory
        3、数据加密工具，就是把服务提供商的信息写入到数据库时，是否需要做什么加密操作
        spring 默认的JdbcUsersConnectionRepository用于mysql 8.0会有rank关键字的bug，所以要重写
        //        JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
         */
        MysqlJdbcUserConnectionRepository repository = new MysqlJdbcUserConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
        //设置userconnection表的前缀，如果公司有规定，表有前缀，不能直接用userconnection做表名，那可以在这里设置前缀
        repository.setTablePrefix("");
        //配置自动注册的程序，配置后，如果sp返回的信息在userconnection中查不到，就会调用此接口做自动注册。如果没有配置此ConnectionSignUp，则会跳转页面
        if(connectionSignUp != null) {
            repository.setConnectionSignUp(connectionSignUp);
        }
        return repository;
    }

    @Override
    public UserIdSource getUserIdSource() {
        return new AuthenticationNameUserIdSource();
        //        return super.getUserIdSource();
    }


    @Bean
    public SpringSocialConfigurer springSocialConfigurer(){
        SpringSocialConfigurer socialConfigurer = new SpringSocialConfigurer();
        //配置自定义注册页面
        socialConfigurer.signupUrl("/signup");
        return socialConfigurer;
    }

    /**
     * spring提供的工具类，用于在其他页面（主要是注册页）获取social的信息
     * @param connectionFactoryLocator
     * @return
     */
    @Bean
    public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator){
        return new ProviderSignInUtils(connectionFactoryLocator,getUsersConnectionRepository(connectionFactoryLocator));
    }
}
